/****************************************
*  顺序串
 *  Created by zephyrus on 2024/6/27.
*****************************************/
#include "SString.h"

/**
 * 初始化
 * @param s
 */
void InitString(String s)
{
    s[0] = '\0';
}

/**
 * 打印
 * @param s
 */
void PrintString(String s)
{
    printf("%s\n", s);
}

/**
 * 赋值
 * @param s
 * @param str
 */
void StrAssign(String s, char *str)
{
    int len = strlen(str);
    for (int i = 0; i < len; ++i)
    {
        s[i] = str[i];
    }
    s[len] = '\0'; //设置字符串结束符
}

/**
 * 拷贝
 * @param s
 * @param t
 */
void StrCopy(String s, String t)
{
    int len = StrLength(t);
    for (int i = 0; i < len; ++i)
    {
        s[i] = t[i];
    }
    s[len] = '\0';
}

/**
 * 判断是否为空
 * @param s
 * @return
 */
bool StrEmpty(String s)
{
    return s[0] == '\0';
}

/**
 * 字符串比较
 * @param s
 * @param t
 * @return
 */
int StrCompare(String s, String t)
{
    int result = 0;
    while (*s != '\0' || *t != '\0')
    {
        result = *s - *t; //做差
        if (result != 0)
        { //不相等
            break;
        }
        //相等
        s++;
        t++;
    }
    if (result > 0)
    {
        result = 1;
    } else if (result < 0)
    {
        return -1;
    }
    //相等
    return result;
}

/**
 * 长度
 * @param s
 * @return
 */
int StrLength(String s)
{
    int len = 0;
    while (*s != '\0')
    {
        len++;
        s++;
    }
    return len;
}

void StrConcat(String t, String s1, String s2)
{
    int len1 = StrLength(s1);
    int len2 = StrLength(s2);
    int i = 0, j = 0;
    //放入s1
    while (i < len1)
    {
        t[i] = s1[i];
        ++i;
    }
    //T的最大长度大于len1+len2，两个能够完全拼接
    if (len1 + len2 <= MAXSTRLEN)
    {
        //接上s2
        while (j < len2)
        {
            t[i + j] = s2[j];
            ++j;
        }
    }
        //T的最大长度大于len1小于len1+len2，只能拼接s1和s2的前面部分
    else if (len1 < MAXSTRLEN)
    {
        while (j < MAXSTRLEN - len1)
        {
            t[i + j] = s2[j];
            ++j;
        }
    }
    //T只能存入s1,只完成s1的拼接，s2被舍弃
    t[i + j] = '\0';

}

/**
 * 取子串:将字符串s中pos位置开始的len个字符给sub
 * @param s
 * @param sub
 * @param pos
 * @param len
 */
void SubString(String s, String sub, int pos, int len)
{
    int s_len = StrLength(s);
    //取取子串条件,不符退出
    if (pos < 0 || pos >= s_len || len < 0 || len > s_len)
        return;
    //设置取子串的开始位置
    int j = pos;
    //从开始位置取出字符传给sub
    for (int i = 0; i < len; ++i)
    {
        sub[i] = s[j + 1];
    }
    sub[len] = '\0';
}

/**
 * 字符串插入：将字符串T插入到S的pos位置
 * @param s
 * @param pos
 * @param t
 */
void StrInsert(String s, int pos, String t)
{
    int s_len = StrLength(s);
    int t_len = StrLength(t);
    if (s_len + t_len > MAXSTRLEN)
    {
        t_len = MAXSTRLEN - s_len; //获取能够添加的个数
    }
    //如果两个字符串的长度和没有超出定长串结构的最大长度，则直接插入
    //移动S中的元素，为插入字符串T腾出空间
    for (int i = s_len - 1; i >= pos; --i)
    {
        //移动元素，从后往前，从s_len-1到pos的每个元素都后移t_len个位置
        s[i + t_len] = s[i];
    }
    int j = pos;//设置开始插入的位置
    for (int i = 0; i < t_len; ++i)
    {
        s[j + i] = t[i];
    }
    s[s_len + t_len] = '\0';
}

/**
 * 删除字符串：删除字符串S从pos位置开始的len长度子串
 * @param s
 * @param pos
 * @param len
 */
void StrDelete(String s, int pos, int len)
{
    int s_len = StrLength(s);
    for (int i = pos + len; i < s_len; ++i)
    {
        s[i - len] = s[i];
    }
    s[s_len - len] = '\0';
}

/**
 * 清空
 * @param s
 */
void StrClear(String s)
{
    s[0] = '\0';
}

/**
 * 模式匹配
 * @param s
 * @param t
 * @param pos
 * @return
 */
int StrIndex(String s, String t, int pos)
{
    int i = pos;//主串开始匹配的初始位置
    int j = 0; //模式串开始匹配的初始位置
    //如果还没匹配到模式串且主串中还有字符，则继续匹配
    while (s[i] != '\0' && t[j] != '\0')
    {
        //如果有字符匹配则将主串和模式串分别下移一个字符
        if (s[i] == t[j])
        {
            i++;
            j++;
        }
            //如果在匹配的过程中，中断了，出现了不匹配
        else
        {
            i = i - j + 1;//将主串的i回溯j-1个字符(j-1可看成先回退j个，再下移一个)
            j = 0;//模式串走的j个位置全部回退，即变为0
        }
    }
    //退出原因如果是因为，模式串匹配完成，则返回子串出现的首位置
    if (t[j] == '\0')
    {
        return i - j;
    }
    //如果没有匹配到，则返回-1
    return -1;
}

/**
 * 替换:替换字符串：将字符串S中出现的T全部替换成V
 * @param s
 * @param t
 * @param v
 */
void StrReplace(String s, String t, String v)
{
    int s_len = StrLength(s);
    int t_len = StrLength(t);
    int v_len = StrLength(v);

    int index = -1;//初始化替换的首位置
    int pos = 0;//记录当前匹配到的位置

    while (pos < s_len)
    {
        index = StrIndex(s, t, pos);
        if (index == -1)
        {
            return;
        }
        //如果找到了，则将该模式串从index这个位置中删除
        StrDelete(s, index, t_len);
        //再将要替换的串从index这个位置中插入
        StrInsert(s, index, v);
        //记录此时匹配到的位置
        pos = index + v_len;//这个位置是替换前模式串所在的首位置加上替换的字符串长度
    }
}